package com.sean.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 日期转换工具类
 * 
 */
public final class DateUtils extends org.apache.commons.lang.time.DateUtils {

	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

	private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");

	private static final SimpleDateFormat CHINADATE_FORMAT = new SimpleDateFormat("yyyy年MM月dd日");
	
	private static final SimpleDateFormat TRSINSERTDATE_FORMAT = new SimpleDateFormat("yyyy年MM月dd日HH时MM分ss秒a");
	
	private static final SimpleDateFormat TRSREADDATE_FORMAT = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");

	public static final String KEY_DATEPATTERN = "yyyyMMddHHmmssSSS";
	
	public static final String KEY_DATEPATTERN_YMD = "yyyyMMdd";

	private static Map<Integer, String> weekMap = Collections.synchronizedMap(new HashMap<Integer, String>());

	static {
		weekMap.put(1, "星期一");
		weekMap.put(2, "星期二");
		weekMap.put(3, "星期三");
		weekMap.put(4, "星期四");
		weekMap.put(5, "星期五");
		weekMap.put(6, "星期六");
		weekMap.put(7, "星期日");
	}

	public static String convertToFormat(Date date, String pattern) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
		return simpleDateFormat.format(date);
	}

	/**
	 * @param date
	 * @return
	 */
	public static String convertToDateTime(Date date) {
		return DATETIME_FORMAT.format(date);
	}

	/**
	 * @param date
	 * @return
	 */
	public static String convertToDate(Date date) {
		return DATE_FORMAT.format(date);
	}

	/**
	 * @param date
	 * @return
	 */
	public static String convertToTime(Date date) {
		return TIME_FORMAT.format(date);
	}
	
	public static String convertToTrsDate(Date date) {
		String str = TRSINSERTDATE_FORMAT.format(date);
		str = str.replaceAll("AM", "上午");
		str = str.replaceAll("am", "上午");
		str = str.replaceAll("PM", "下午");
		str = str.replaceAll("pm", "下午");
		return str;
	}

	public static String dayForWeek(Date pTime) {

		String chinaDate = CHINADATE_FORMAT.format(pTime);
		Calendar c = Calendar.getInstance();
		c.setTime(pTime);
		int dayForWeek = 0;
		if (c.get(Calendar.DAY_OF_WEEK) == 1) {
			dayForWeek = 7;
		} else {
			dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
		}
		return chinaDate + " " + weekMap.get(dayForWeek);
	}
	
	/**
	 * 根据指定的格式得到时间戳
	 * @param pattern 指定的格式
	 * @return 指定格式的时间戳
	 */
	public static String getTimeStampByPattern(String pattern){
		return new SimpleDateFormat(pattern).format(new Date()) ;
	}
	
	/**
	 * 根据指定的格式得到指定时间的时间戳
	 * @prram date 指定的时间
	 * @param pattern 指定的格式
	 * @return 指定格式的时间戳
	 */
	public static String format(Date date, String pattern){
		return new SimpleDateFormat(pattern).format(date);
	}
	
	/**
	 * 根据指定的格式得到指定时间
	 * @prram date 指定的时间字符串
	 * @param pattern 指定的格式
	 * @return 指定格式的时间
	 * @throws ParseException 
	 */
	public static Date parse(String date, String pattern) throws ParseException {
		return new SimpleDateFormat(pattern).parse(date);
	}
	
	public static Date getDateByString(String str){
		SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		Date dateTime = null;
		try {
			dateTime = sim.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return dateTime;
	}
	/**
	 * 起始日期与终止日期之间的天数(包含这两天)
	 * @param startDate
	 * @param endDate
	 * @return
	 * @throws ParseException
	 */
	public static int getDays(Date startDate, Date endDate) throws ParseException {
		if(startDate != null && endDate != null) {
			startDate = parse(format(startDate, KEY_DATEPATTERN_YMD), KEY_DATEPATTERN_YMD);
			endDate = parse(format(endDate, KEY_DATEPATTERN_YMD), KEY_DATEPATTERN_YMD);
			return (int) Math.floor((endDate.getTime() - startDate.getTime())/(1000 * 60 * 60 * 24)) + 1;
		}
		return -1;
	}
	
	/**
	 * 获取指定时间所在月的第一天的开始时间
	 * @param date
	 * @return
	 */
	public static String getStartMonthDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(GregorianCalendar.DAY_OF_MONTH, 1);
		return format(cal.getTime(), "yyyy-MM-dd 00:00:00");
	}
	
	/**
	 * 获取指定时间所在月的最后一天的结束时间
	 * @param date
	 * @return
	 */
	public static String getEndMonthDate(Date date){
		Calendar cal = Calendar.getInstance();   
		cal.setTime(date);
	    cal.set( Calendar.DATE, 1 );  
	    cal.roll(Calendar.DATE, - 1 );  
		return format(cal.getTime(), "yyyy-MM-dd 23:59:59");
	}
	
	/**
	 * 获取月历.
	 * @param date
	 * @param monFirst
	 * @return
	 */
	public static List<List<Date>> getCalendar(Date date) {
		List<Date> list = new ArrayList<Date>();
		Date startDay = getDateByString(getStartMonthDate(date));
		int weekDays = getWeekDaysByDate(startDay);
		if(weekDays > 1) {
			startDay = addDays(startDay, (weekDays-1)*-1);
		}
		Date endDay = getDateByString(getEndMonthDate(date));
		weekDays = getWeekDaysByDate(endDay);
		if(weekDays < 7) {
			endDay = addDays(endDay, (7-weekDays));
		}
		Date tempDate = startDay;
		while(tempDate.getTime() < endDay.getTime()) {
			list.add(tempDate);
			tempDate = addDays(tempDate, 1);
		}
		List<List<Date>> calendarList = new ArrayList<List<Date>>();
		List<Date> weekList = null;
		for (Date day : list) {
			if(DateUtils.getWeekDaysByDate(day) == 1) {
				weekList = new ArrayList<Date>();
				calendarList.add(weekList);
			}
			weekList.add(day);
		}
		return calendarList;
	}
	
	/**
	 * 获取某日是每周第几天.
	 * @param day
	 * @return
	 */
	public static int getWeekDaysByDate(Date day) {
		Calendar cal=Calendar.getInstance(); 
		cal.setTime(day);
		return cal.get(Calendar.DAY_OF_WEEK);
	}
	
	public static void main(String[] args) throws ParseException {
		System.out.println(parse("2013-08", "yyyy-MM"));
		
		for (List<Date> week : getCalendar(parse("2013-07", "yyyy-MM"))) {
			for (Date date : week) {
				System.out.print("  " + format(date, "MM-dd"));
			}
			System.out.println("");
		}
	}

}
